Skip to content

feat(providers): add Zhipu AI GLM provider (open.bigmodel.cn) - #536

Closed
Lucinegogo wants to merge 2 commits into
lidge-jun:devfrom
Lucinegogo:feat/glm-provider
Closed

feat(providers): add Zhipu AI GLM provider (open.bigmodel.cn)#536
Lucinegogo wants to merge 2 commits into
lidge-jun:devfrom
Lucinegogo:feat/glm-provider

Conversation

@Lucinegogo

@Lucinegogo Lucinegogo commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds Zhipu AI — GLM (open.bigmodel.cn/api/paas/v4) as a built-in key-auth provider, so OpenAI Codex CLI / Claude Code can route through GLM via opencodex.

This complements the existing zai entry, which targets the z.ai international coding-plan subscription. The new glm entry targets Zhipu's domestic OpenAI-compatible pay-as-you-go endpoint — same GLM model family, different host and billing.

Changes

  • src/providers/registry.ts: append a glm entry to PROVIDER_REGISTRY (after zai).
    • baseUrl: https://open.bigmodel.cn/api/paas/v4
    • adapter: openai-chat, authKind: "key" (Bearer JWT)
    • defaultModel: glm-4.6
    • liveModels: true so newly published GLM ids surface in the picker without a registry edit
    • thinkingToggleModels: ["glm-4.6"] + reuse of the shared THINKING_TOGGLE_EFFORTS / THINKING_TOGGLE_MAP, since GLM-4.6 exposes the binary thinking: {type: "enabled" | "disabled"} knob
  • tests/provider-registry-parity.test.ts: append "glm" to EXPECTED_KEY_PROVIDER_IDS so the key-login export is derived from the registry parity test stays green.

No other surfaces need changes — CLI, GUI, docs-site provider pickers are all derived from PROVIDER_REGISTRY.

Evidence

Test plan

  • bun test tests/provider-registry-parity.test.ts — passes with glm in EXPECTED_KEY_PROVIDER_IDS
  • ocx provider add glm --api-key <zhipu-jwt> registers the provider
  • ocx start then selecting Zhipu AI — GLM in Codex CLI routes a chat completion to https://open.bigmodel.cn/api/paas/v4/chat/completions successfully
  • With reasoning_effort: "high" selected in Codex, the upstream request body carries thinking: {type: "enabled"} and returns reasoning content

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added support for the Zhipu AI GLM provider.
    • Set GLM-4.6 as the default model, with live model discovery and configurable reasoning options.
    • Added support for the provider’s OpenAI-compatible endpoint and API key authentication.

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

Target branch corrected

This pull request now targets dev.

The [WRONG BRANCH] title prefix has been removed. The pull request has been marked ready for review again.

@github-actions github-actions Bot added the enhancement New feature or request label Jul 27, 2026
@github-actions github-actions Bot changed the title feat(providers): add Zhipu AI GLM provider (open.bigmodel.cn) [WRONG BRANCH] feat(providers): add Zhipu AI GLM provider (open.bigmodel.cn) Jul 27, 2026
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds the glm Zhipu AI provider with GLM model discovery, reasoning settings, and key authentication, then updates the provider parity test’s expected key-provider IDs.

Changes

GLM provider

Layer / File(s) Summary
Provider registration and parity validation
src/providers/registry.ts, tests/provider-registry-parity.test.ts
Registers glm against open.bigmodel.cn with glm-4.6 as the default model, live discovery, reasoning mappings, and preserved reasoning content; updates the expected key-provider ID list.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related PRs

Suggested reviewers: ingwannu, lidge-jun

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: adding the Zhipu AI GLM provider for open.bigmodel.cn.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/provider-registry-parity.test.ts`:
- Line 35: Extend the provider parity test beyond checking that "glm" is listed:
retrieve the GLM entry from the expected provider registry and assert its
baseUrl, adapter/auth configuration, default model, liveModels, and thinking
mappings match the contract defined in the GLM registry entry. Keep the
assertions focused near the existing provider-list coverage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ae8abb9b-a3b6-4171-a18e-c743096d4e8b

📥 Commits

Reviewing files that changed from the base of the PR and between 7ba0fec and 26e5184.

📒 Files selected for processing (2)
  • src/providers/registry.ts
  • tests/provider-registry-parity.test.ts

"anthropic-apikey", "openai-apikey", "umans", "opencode-go", "neuralwatt", "openrouter", "orcarouter", "bizrouter", "groq", "google", "google-vertex", "azure-openai",
"deepseek", "cerebras", "together", "fireworks", "firepass", "moonshot",
"huggingface", "nvidia", "venice", "zai", "nanogpt", "synthetic", "siliconflow", "qwen-cloud", "tencent-coding-plan",
"huggingface", "nvidia", "venice", "zai", "glm", "nanogpt", "synthetic", "siliconflow", "qwen-cloud", "tencent-coding-plan",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the GLM provider contract, not only its ID.

This test only proves that "glm" appears in the expected key-provider list. It will not catch an incorrect baseUrl, adapter/auth configuration, default model, liveModels, or thinking mappings in src/providers/registry.ts Lines 795-808. Add a focused assertion that retrieves the glm entry and verifies those fields.

As per path instructions, a behavior change in src/ should come with a focused regression test near the existing subsystem tests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/provider-registry-parity.test.ts` at line 35, Extend the provider
parity test beyond checking that "glm" is listed: retrieve the GLM entry from
the expected provider registry and assert its baseUrl, adapter/auth
configuration, default model, liveModels, and thinking mappings match the
contract defined in the GLM registry entry. Keep the assertions focused near the
existing provider-list coverage.

Source: Path instructions

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 26e518407f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/providers/registry.ts
authKind: "key",
dashboardUrl: "https://bigmodel.cn/console/usercenter/apikeys",
defaultModel: "glm-4.6",
models: ["glm-4.6", "glm-4.5", "glm-4-plus", "glm-4-air", "glm-4-airx", "glm-4-flash", "glm-4-flashx", "glm-4-long", "glm-4v"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Advertise image input for GLM-4V

When glm-4v is selected, the catalog publishes it as text-only because this provider supplies no modelInputModalities entry and the generic catalog fallback is ["text"]; live /models parsing does not infer image capability either. Codex therefore blocks image attachments before they can reach this vision model. Add explicit glm-4v: ["text", "image"] capability metadata.

Useful? React with 👍 / 👎.

Comment thread src/providers/registry.ts
Comment on lines +805 to +808
thinkingToggleModels: ["glm-4.6"],
modelReasoningEfforts: { "glm-4.6": THINKING_TOGGLE_EFFORTS },
modelReasoningEffortMap: { "glm-4.6": THINKING_TOGGLE_MAP },
preserveReasoningContentModels: ["glm-4.6"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add a focused GLM request-shaping regression test

The test change only adds glm to the expected provider-id list, so it never exercises the newly declared thinking-toggle or reasoning-history behavior. Add a focused test that routes glm/glm-4.6 and verifies effort mapping produces thinking: { type: "enabled" | "disabled" } rather than reasoning_effort, plus the intended reasoning_content replay; otherwise the central behavior introduced here can regress while the parity test remains green.

AGENTS.md reference: AGENTS.md:L75-L77

Useful? React with 👍 / 👎.

Comment thread src/providers/registry.ts
// coding-plan subscription. Live model discovery is enabled so newly published GLM ids
// surface automatically without a registry edit. Evidence: docs.bigmodel.cn/api-reference.
{
id: "glm",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid commandeering the existing glm provider name

When upgrading an existing config with a user-defined provider named glm, routedProviderConfig now recognizes this registry id and, because allowBaseUrlOverride is not enabled, silently replaces the saved endpoint with open.bigmodel.cn. The repository already assigns glm in FREE_PROVIDER_DIRECTORY to Z.AI at https://api.z.ai/api/coding/paas/v4, so a config created from that identity will suddenly send requests and its API key to a different host. Use an unused id such as glm-cn/zhipu-bigmodel, or add an explicit migration that does not retarget existing custom entries.

AGENTS.md reference: AGENTS.md:L65-L70

Useful? React with 👍 / 👎.

Comment thread src/providers/registry.ts
adapter: "openai-chat",
authKind: "key",
dashboardUrl: "https://bigmodel.cn/console/usercenter/apikeys",
defaultModel: "glm-4.6",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Declare GLM-4.6's full context window

The new default model has neither a modelContextWindows entry nor a metadata bundle alias, so whenever live discovery fails or returns the ordinary OpenAI model-list shape without context_length, catalog normalization advertises only the generic 128,000-token fallback. The repository's generated GLM metadata records glm-4.6 at 204,800 tokens, meaning Codex compacts or truncates roughly 76,800 tokens early for this preset. Add the explicit context window or connect this provider to the appropriate GLM metadata bundle.

Useful? React with 👍 / 👎.

Comment thread src/providers/registry.ts
Comment on lines +793 to +795
id: "glm",
label: "Zhipu AI — GLM",
baseUrl: "https://open.bigmodel.cn/api/paas/v4",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Document the domestic BigModel preset

This adds a user-selectable provider with a distinct endpoint and billing product, but the public provider catalog still documents only the Z.AI coding-plan endpoint and never explains the new glm route. Update the English provider guide and its translated tables so users can distinguish the domestic pay-as-you-go preset from zai and configure the intended credential and route.

AGENTS.md reference: AGENTS.md:L78-L79

Useful? React with 👍 / 👎.

@Ingwannu

Copy link
Copy Markdown
Owner

Closing the current revision. The domestic BigModel preset can be useful, but this head is not safe to merge.

  1. The PR targets main; contributions must target dev.
  2. glm is already an existing provider identity in FREE_PROVIDER_DIRECTORY, currently bound to the Z.AI coding endpoint. Registering the same id as open.bigmodel.cn lets registry hydration silently retarget a saved glm configuration and send its API key to a different host. This requires an unused stable id such as zhipu-bigmodel, or an explicit migration that cannot retarget existing credentials.
  3. The provider contract is incomplete: focused request-shaping coverage, GLM-4V image modality, the authoritative GLM-4.6 context window, and public/localized provider documentation are missing.

Please retarget to dev, choose a non-colliding provider id, add the missing metadata/docs/regressions, and reopen or submit a corrected PR. We will review the corrected version.

@Ingwannu Ingwannu closed this Jul 27, 2026
@lidge-jun lidge-jun reopened this Jul 27, 2026
@lidge-jun
lidge-jun changed the base branch from main to dev July 27, 2026 08:41
@lidge-jun
lidge-jun requested a review from Wibias as a code owner July 27, 2026 08:41
@github-actions github-actions Bot changed the title [WRONG BRANCH] feat(providers): add Zhipu AI GLM provider (open.bigmodel.cn) feat(providers): add Zhipu AI GLM provider (open.bigmodel.cn) Jul 27, 2026
@lidge-jun

Copy link
Copy Markdown
Owner

Reopening this, and I've retargeted it to dev for you — sorry for the churn. I closed it a bit too bluntly earlier: the idea here is a real gap in our provider list, and it deserved a path forward rather than a closure notice.

To be concrete about what I changed on the PR itself: GitHub refuses a base change on a closed PR, so the order was reopen first, then retarget maindev, then drop the [WRONG BRANCH] prefix the automation added. Nothing about your commits was touched.

Why I'm folding a maintainer contribution on top

maintainerCanModify is false on Lucinegogo:feat/glm-provider, so I can't push the corrections onto your branch. Instead I'm landing them as commits on dev with Co-authored-by: Lucinegogo, and this PR stays as the thread where the reasoning lives. The endpoint research, the thinking-toggle finding, and the shape of the entry are yours — I'm finishing the parts that need repository-specific knowledge.

The one release blocker, with the exact mechanism

The glm id is already taken. src/providers/free-directory.ts:106 binds it to https://api.z.ai/api/coding/paas/v4, and routedProviderConfig() in src/router.ts:188 resolves a saved provider against PROVIDER_REGISTRY by id. At src/router.ts:233-236:

const baseUrl = (registryBaseUrlIsTemplate || registryEntry.allowBaseUrlOverride) && userBaseUrlIsResolved
  ? userBaseUrl
  : registryEntry.baseUrl;

Your entry sets neither allowBaseUrlOverride nor a template placeholder, so a user who already has a glm provider saved against Z.AI would, after upgrading, have their config silently canonicalized onto open.bigmodel.cn — their Z.AI key sent to a different vendor's host on the next request. That's the reason I couldn't merge the head as-is.

glm-cn is taken too (same file, line 107, pointing at the BigModel coding-plan path). The id I'm using is zhipu-bigmodel, which is free in both namespaces.

Worth saying plainly: our tests would not have caught this. The isolation test at tests/provider-registry-parity.test.ts:796 only checks directory rows with supportLevel: "reference", and glm is supported. So this was a trap the repository left for you, not a mistake you should have anticipated. I'm adding a generalized guard so the next person gets a failing test instead of a review comment.

The rest of the corrections

  • Context window. No modelContextWindows entry means catalog normalization falls back to a generic 128,000 window. Our own metadata bundle records glm-4.6 at 204,800 (src/generated/jawcode-model-metadata.ts, zai rows), so Codex was compacting roughly 76,800 tokens early. Fixed by declaring it explicitly and wiring jawcodeBundle: "zai" so the rest of the family inherits authoritative numbers.
  • Model list. glm-4-plus / glm-4-air / glm-4-airx / glm-4-long / glm-4v are the older GLM-4 generation and we hold no context or modality facts for them. Swapped for ids the bundle already covers: glm-4.6, glm-4.7, glm-4.7-flash, glm-5, glm-5.1, plus glm-4.6v for vision. glm-4.6 stays the default, as you had it.
  • Modalities. Declared per model via modelInputModalities. One repo-specific gotcha: noVisionModels here does not mean "text only" — src/codex/catalog/provider-fetch.ts:98-105 uses it to add image input so attachments reach the proxy's vision sidecar. Since nobody has verified sidecar coverage for BigModel-hosted GLM, the entry declares modalities directly and lists nothing there.
  • liveModels. Dropped for now. I haven't seen GET /api/paas/v4/models respond on open.bigmodel.cn, and a liveModels: true that 404s produces an empty picker at runtime. Static list plus the metadata bundle is the honest default.
  • Tests. The parity append proves an id exists; it can't catch a wrong baseUrl, a broken effort map, or a regression at src/adapters/openai-chat.ts:561 where thinkingToggleModels membership is what turns a mapped effort into thinking: { type } instead of reasoning_effort. Adding a focused test file that asserts the contract and builds a request through the adapter to check both the enabled and disabled halves of the toggle.
  • Docs. Adding the row and a short "two GLM routes" note to docs-site/src/content/docs/guides/providers.md and the ko / ja / ru / zh-cn tables, so the domestic pay-as-you-go preset is distinguishable from the zai coding plan.

What I can't do without you

Verifying liveModels against a real Zhipu key. If GET https://open.bigmodel.cn/api/paas/v4/models returns an OpenAI-shaped list for you, say so here and I'll flip it on — it's a one-line change and it makes the picker much nicer.

Thanks for this. The routing analysis in your description was accurate and the thinking-toggle citation saved me a lookup; the collision was a repository sharp edge, and it's getting sanded down because you hit it.

@lidge-jun

Copy link
Copy Markdown
Owner

Landed on dev, with you as co-author on all three commits:

  • cf0a3230 — the provider entry as zhipu-bigmodel, with jawcodeBundle: "zai" so the GLM families inherit authoritative context windows, glm-4.6 pinned at 204,800, per-model modalities, and the thinking toggle mapped onto thinking: {type}.
  • 224db1a5 — the focused tests, plus the generalized directory/registry guard.
  • 7de1a3ce — the provider docs across en / ko / ja / ru / zh-cn.

Two things worth reporting back:

The new guard fails on the original shape. I mutated the id back to glm and re-ran: all four new tests fail and the generalized isolation guard fails. So the trap that let this through review is now closed — that's a direct result of you walking into it.

liveModels is the one open item. I left it off since I can't confirm GET /api/paas/v4/models answers on that host. If it returns an OpenAI-shaped list with your key, say so and I'll flip it on.

Verification: bun run typecheck clean, full suite 4996 pass / 0 fail.

I'm leaving this PR open rather than closing it — it's the record of where the design came from, and I'd rather it read as your contribution with maintainer follow-through than as a closed PR with a separate commit somewhere else.

lidge-jun added a commit that referenced this pull request Jul 27, 2026
Adds focused coverage for zhipu-bigmodel: the provider contract, the
thinking-toggle request shaping (both the enabled and disabled halves,
built through the real adapter), and the derived key-login/preset/bundle
surfaces.

Also generalizes the directory isolation rule. The existing guard only
checked directory rows with supportLevel "reference", so re-registering
a CONNECTABLE id against a different host stayed green — which is why
#536 could propose `glm` for open.bigmodel.cn while `glm` was already
bound to api.z.ai. The new case fails on exactly that shape.

Mutation-verified: reverting the id to `glm` fails all four new tests
plus the generalized guard, and removing thinkingToggleModels fails only
the request-shaping test.

Co-authored-by: Lucinegogo <103441383+Lucinegogo@users.noreply.github.com>
@lidge-jun

Copy link
Copy Markdown
Owner

Heads up, and thanks for the contribution — the BigModel provider has landed on dev (cf0a3230), so this PR is now superseded by work that grew out of reviewing it.

Two things came out of that review and both changed the shape of the final version:

The glm id collides. zhipu-glm already exists in the registry as the international z.ai route. Registering a second provider as glm gives two entries that resolve the same model names against different hosts, and the router has no way to tell them apart. The landed version uses zhipu-bigmodel and the docs now name the two routes explicitly in every locale, so users can see which one they are picking.

The model list needed refreshing. This PR pins glm-4.5 / glm-4-plus / the glm-4-* family, which BigModel has since moved past. The landed list is glm-4.6, glm-4.7, glm-4.7-flash, glm-5, glm-5.1, plus glm-4.6v for vision, with input modalities and the thinking toggle set per model rather than for the whole provider.

Closing this one as superseded rather than merging it, since the two would now conflict in the registry. The idea and the endpoint research were yours and they carried straight through — if anything in the landed version looks wrong to you, say so and I will fix it.

@lidge-jun lidge-jun closed this Jul 27, 2026
@lidge-jun

Copy link
Copy Markdown
Owner

Shipped — this is now on dev, with you credited as co-author on all three commits:

  • cf0a3230 — the provider entry as zhipu-bigmodel
  • 224db1a5 — the focused tests and the generalized id-collision guard
  • 7de1a3ce — the provider docs across en / ko / ja / ru / zh-cn

I'm closing this PR as superseded, not rejected. The branch here still carries the original glm id, so merging it would conflict with what landed and would re-introduce the endpoint-hijack path we just closed off. The idea, the endpoint research, and the thinking-toggle citation are all in the shipped code — GitHub will show these commits under your contributions.

One thing I'd genuinely like your help with: I left liveModels off because I couldn't confirm GET https://open.bigmodel.cn/api/paas/v4/models answers. If it returns an OpenAI-shaped list with your key, open a small PR against dev flipping it on — that one's yours to land directly.

Thanks for pushing on this. The glm collision was a trap the repository left lying around, and it's fixed for the next person because you walked into it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants